home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 April: Mac OS SDK / Dev.CD Apr 99 SDK1.toast / Development Kits / Zoomed Video Driver v1.0 SDK / Tools / PC Card DispNameReg / Src / AppleEventCore.c next >
Encoding:
C/C++ Source or Header  |  1997-06-02  |  24.8 KB  |  1,123 lines  |  [TEXT/CWIE]

  1. /*                                    AppleEventCore.c                            */
  2. /*
  3.  * AppleEventCore.c
  4.  * Copyright © 1988-94 Apple Computer Inc. All rights reserved.
  5.  * Note: a lot of these functions are not (yet) used.
  6.  */
  7. #include "AppleEventCore.h"
  8. #include <AERegistry.h>
  9. #include <AppleTalk.h>
  10. #include <Gestalt.h>
  11. #include <Dialogs.h>
  12. #include <Errors.h>
  13. #include <Script.h>
  14. #include <TextUtils.h>
  15. #include <Kernel.h>
  16.  
  17. #ifndef FALSE
  18. #define FALSE        0
  19. #define TRUE        1
  20. #endif
  21.  
  22. AECoreGlobals                    gAECoreGlobals;
  23. #define GLOBAL                    (gAECoreGlobals)
  24. Boolean                            gHasAppleEvents;
  25. static AEOpenAppHandlerFunc        gAEOpenAppHandlerFunc;
  26. static AEDocumentHandlerFunc    gAEOpenDocHandlerFunc;
  27. static AEDocumentHandlerFunc    gAEPrintDocHandlerFunc;
  28. static AEQuitAppHandlerFunc        gAEQuitAppHandlerFunc;
  29. static AEDoScriptHandlerFunc    gAEDoScriptHandlerFunc;
  30. static AEUnknownHandlerMsgFunc    gAEUnknownHandlerMsgFunc;
  31.  
  32. static pascal OSErr            AEOpenApplication(
  33.         const AppleEvent        *theEvent,
  34.         AppleEvent                *theReply,
  35.         long                    refCon
  36.     );
  37. static pascal OSErr            AEOpenDocument(
  38.         const AppleEvent        *theEvent,
  39.         AppleEvent                *theReply,
  40.         long                    refCon
  41.     );
  42. static pascal OSErr            AEPrintDocument(
  43.         const AppleEvent        *theEvent,
  44.         AppleEvent                *theReply,
  45.         long                    refCon
  46.     );
  47. static pascal OSErr            AEQuit(
  48.         const AppleEvent        *theEvent,
  49.         AppleEvent                *theReply,
  50.         long                    refCon
  51.     );
  52. static OSErr                AEOpenOrPrint(
  53.         const AppleEvent        *theEvent,
  54.         AppleEvent                *theReply,
  55.         long                    refCon,
  56.         AEDocumentHandlerFunc    aeDocumentHandlerFunc
  57.     );
  58. static pascal OSErr            AEUnknownHandler(
  59.         const AppleEvent        *theEvent,
  60.         AppleEvent                *theReply,
  61.         long                    refCon
  62.     );
  63. static pascal OSErr            AEDoScript(
  64.         const AppleEvent        *theEvent,
  65.         AppleEvent                *theReply,
  66.         long                    refCon
  67.     );
  68. static void                    AEGetMyZone(
  69.         Str32                    zoneName
  70.     );
  71.  
  72. /*
  73.  * Define a table used to install event handlers.
  74.  */
  75. const static AEHandlerDefRec    gAEHandlerDefs[] = {
  76.     { kCoreEventClass,    kAEStartRecording,            AEIgnore                    },
  77.     { kCoreEventClass,    kAEStopRecording,            AEIgnore                    },
  78.     { kCoreEventClass,    kAENotifyRecording,            AEIgnore                    },
  79.     { kCoreEventClass,    kAENotifyStopRecording,        AEIgnore                    },
  80.     { kCoreEventClass,    kAENotifyStartRecording,    AEIgnore                    },
  81.     { kCoreEventClass,    kAEOpenApplication,            AEOpenApplication            },
  82.     { kCoreEventClass,    kAEOpenDocuments,            AEOpenDocument                },
  83.     { kCoreEventClass,    kAEPrintDocuments,            AEPrintDocument                },
  84.     { kCoreEventClass,    kAEQuitApplication,         AEQuit                        },
  85.     { 0,                0,                            NULL                        }
  86. };
  87.  
  88. #define UNUSED(what)    (what)
  89.  
  90. static void                    ClearMemory(
  91.         register void            *ptr,
  92.         register long            size
  93.     );
  94. #define CLEAR(rec)    (ClearMemory(&rec, sizeof rec))
  95. static void                    pstrcpy(
  96.         StringPtr                dst,
  97.         ConstStr255Param        src
  98.     );
  99. static void                    pstrcat(
  100.         StringPtr                dst,
  101.         ConstStr255Param        src
  102.     );
  103.  
  104. pascal OSErr
  105. InitializeAppleEvents(
  106.         AEOpenAppHandlerFunc    aeOpenAppHandlerFunc,
  107.         AEDocumentHandlerFunc    aeOpenDocHandlerFunc,
  108.         AEDocumentHandlerFunc    aePrintDocHandlerFunc,
  109.         AEQuitAppHandlerFunc    aeQuitAppHandlerFunc,
  110.         AEDoScriptHandlerFunc    aeDoScriptHandlerFunc,
  111.         AEUnknownHandlerMsgFunc    aeUnknownHandlerMsgFunc,
  112.         long                    refCon
  113.     )
  114. {
  115.         long                    response;
  116.         OSErr                    status;
  117.  
  118.         status = Gestalt(gestaltAppleEventsAttr, &response);
  119.         gHasAppleEvents = (
  120.                     status == noErr
  121.                     && (response & (1L << gestaltAppleEventsPresent) != 0)
  122.                 );
  123.         status = (gHasAppleEvents == FALSE) ? gestaltUndefSelectorErr : noErr;
  124.         if (status == noErr) {
  125.             gAEOpenAppHandlerFunc = aeOpenAppHandlerFunc;
  126.             gAEOpenDocHandlerFunc = aeOpenDocHandlerFunc;
  127.             gAEPrintDocHandlerFunc = aePrintDocHandlerFunc;
  128.             gAEQuitAppHandlerFunc = aeQuitAppHandlerFunc;
  129.             gAEDoScriptHandlerFunc = aeDoScriptHandlerFunc;
  130.             gAEUnknownHandlerMsgFunc = aeUnknownHandlerMsgFunc;
  131.             status = AEInstallEventHandlers(
  132.                         (AEHandlerDefPtr) gAEHandlerDefs, refCon);
  133.         }
  134.         if (status == noErr && aeDoScriptHandlerFunc != NULL) {
  135.             status = AEInstallEventHandler(
  136.                         kAEMiscStandards,
  137.                         kAEDoScript,
  138.                         NewAEEventHandlerProc(AEDoScript),
  139.                         0,                        /* No refCon                */
  140.                         FALSE                    /* Not system event            */
  141.             );
  142.         }
  143.         if (status == noErr && aeUnknownHandlerMsgFunc != NULL) {
  144.             status = AEInstallEventHandler(
  145.                         typeWildCard,
  146.                         typeWildCard,
  147.                         NewAEEventHandlerProc(AEUnknownHandler),
  148.                         0,                        /* No refCon                */
  149.                         FALSE                    /* Not system event            */
  150.             );
  151.         }
  152.         return (status);
  153. }
  154.  
  155. /*
  156.  * Initialize for apple events: and setup the handler callbacks so we process
  157.  * events. Fail if a handler can't be installed. The caller should check
  158.  * gHasAppleEvents to see if they are actually present.
  159.  */
  160. pascal OSErr
  161. AEInstallEventHandlers(
  162.         AEHandlerDefPtr            aeHandlerDefPtr,
  163.         long                    refCon
  164.     )
  165. {
  166.         OSErr                    status;
  167.  
  168.         status = noErr;
  169.         if (aeHandlerDefPtr != NULL) {
  170.             while (status == noErr && aeHandlerDefPtr->procPtr != NULL) {
  171.                 status = AEInstallEventHandler(
  172.                             aeHandlerDefPtr->eventClass,
  173.                             aeHandlerDefPtr->eventID,
  174.                             NewAEEventHandlerProc(aeHandlerDefPtr->procPtr),
  175.                             refCon,
  176.                             FALSE                    /* Not system event            */
  177.                 );
  178.                 ++aeHandlerDefPtr;
  179.             }
  180.         }
  181.         return (status);
  182. }
  183.  
  184. /*
  185.  * Initialize for apple events: and setup the coercion callbacks so we process
  186.  * events. Fail if a handler can't be installed. The caller should check
  187.  * gHasAppleEvents to see if they are actually present.
  188.  */
  189. pascal OSErr
  190. AEInstallCoercionHandlers(
  191.         AECoercionDefPtr        aeCoercionDefPtr,
  192.         long                    refCon
  193.     )
  194. {
  195.         OSErr                    status;
  196.  
  197.         status = noErr;
  198.         if (aeCoercionDefPtr != NULL) {
  199.             while (aeCoercionDefPtr->procPtr != NULL) {
  200.                 status = AEInstallCoercionHandler(
  201.                             aeCoercionDefPtr->fromType,
  202.                             aeCoercionDefPtr->toType,
  203.                             NewAECoerceDescProc(aeCoercionDefPtr->procPtr),
  204.                             refCon,
  205.                             FALSE,                    /* Pass data                */
  206.                             FALSE                    /* Not system handler        */
  207.                         );
  208.                 ++aeCoercionDefPtr;
  209.             }
  210.         }
  211.         return (status);
  212. }
  213.  
  214. /*
  215.  * Open (initial double-click) the application. The handler is optional.
  216.  */
  217. static pascal OSErr
  218. AEOpenApplication(
  219.         const AppleEvent        *theEvent,
  220.         AppleEvent                *theReply,
  221.         long                    refCon
  222.     )
  223. {
  224.         OSErr                    status;
  225.         
  226.         status = AEHandlerSetup(theEvent, theReply, refCon);
  227.         if (status == noErr)
  228.             status = AEGotRequiredParams(theEvent);
  229.         if (status == noErr && gAEOpenAppHandlerFunc != NULL)
  230.             status = (*gAEOpenAppHandlerFunc)(refCon);    /* Application specific    */
  231.         GLOBAL.currentEventIsAppleEvent = FALSE;
  232.         return (status);        
  233. }
  234.  
  235.  
  236. /*
  237.  * Open a document. This can be called at application setup, but it can also
  238.  * be called by dropping a document on the application icon.
  239.  */
  240. static pascal OSErr
  241. AEOpenDocument(
  242.         const AppleEvent        *theEvent,
  243.         AppleEvent                *theReply,
  244.         long                    refCon
  245.     )
  246. {
  247.         OSErr                    status;
  248.         
  249.         status = AEOpenOrPrint(theEvent, theReply, refCon, gAEOpenDocHandlerFunc);
  250.         return (status);
  251. }
  252.  
  253. /*
  254.  * Print a document. This can be called at application setup, but it can also
  255.  * be called by dropping a document on the application icon.
  256.  */
  257. static pascal OSErr
  258. AEPrintDocument(
  259.         const AppleEvent        *theEvent,
  260.         AppleEvent                *theReply,
  261.         long                    refCon
  262.     )
  263. {
  264.         OSErr                    status;
  265.  
  266.         status = AEOpenOrPrint(theEvent, theReply, refCon, gAEPrintDocHandlerFunc);
  267.         return (status);
  268. }
  269.  
  270. /*
  271.  * This is the common handler for AppleEvent open document and print document.
  272.  * The actual work is done by application-specific code.
  273.  */
  274. static OSErr
  275. AEOpenOrPrint(
  276.         const AppleEvent        *theEvent,
  277.         AppleEvent                *theReply,
  278.         long                    refCon,
  279.         AEDocumentHandlerFunc    aeDocumentHandlerFunc
  280.     )
  281. {
  282.         OSErr                    status;
  283.         AEDesc                    theDesc;
  284.         long                    numberOfFiles;
  285.         long                    iFile;
  286.         AEKeyword                ignoredKeyWord;
  287.         DescType                ignoredType;
  288.         Size                    ignoredSize;
  289.         FSSpec                    theFSS;
  290.         
  291.         theDesc.dataHandle = NULL;;
  292.         status = (aeDocumentHandlerFunc == NULL) ? errAEEventNotHandled : noErr;
  293.         if (status == noErr)
  294.             status = AEHandlerSetup(theEvent, theReply, refCon);
  295.         if (status == noErr)
  296.             status = AEGetParamDesc(theEvent, keyDirectObject, typeAEList, &theDesc);
  297.         if (status == noErr)
  298.             status = AEGotRequiredParams(theEvent);
  299.         if (status == noErr)
  300.             status = AECountItems(&theDesc, &numberOfFiles);
  301.         for (iFile = 1; status == noErr && iFile <= numberOfFiles; iFile++) {
  302.             status = AEGetNthPtr(
  303.                         &theDesc,
  304.                         iFile,
  305.                         typeFSS,
  306.                         &ignoredKeyWord,
  307.                         &ignoredType,
  308.                         (Ptr) &theFSS,
  309.                         sizeof theFSS,
  310.                         &ignoredSize
  311.                     );
  312.             if (status == noErr) {
  313.                 /*
  314.                  * Note that an error from the handler will terminate all files.
  315.                  */
  316.                 status = (*aeDocumentHandlerFunc)(&theFSS, refCon);
  317.             }
  318.         }
  319.         (void) AEDisposeDesc(&theDesc);
  320.         GLOBAL.currentEventIsAppleEvent = FALSE;
  321.         return (status);
  322. }
  323.  
  324. static pascal OSErr
  325. AEQuit(
  326.         const AppleEvent        *theEvent,
  327.         AppleEvent                *theReply,
  328.         long                    refCon
  329.     )
  330. {
  331.         OSErr                    status;
  332.  
  333.         status = (gAEQuitAppHandlerFunc == NULL) ? errAEEventNotHandled : noErr;
  334.         if (status == noErr)
  335.             status = AEHandlerSetup(theEvent, theReply, refCon);
  336.         if (status == noErr)
  337.             status = AEGotRequiredParams(theEvent);
  338.         status = (*gAEQuitAppHandlerFunc)(refCon);
  339.         GLOBAL.currentEventIsAppleEvent = FALSE;
  340.         return (status);        
  341. }
  342.                 
  343. /*
  344.  * This handler is called for "scripting on/off" events. They are ignored.
  345.  */
  346. pascal OSErr
  347. AEIgnore(
  348.         const AppleEvent        *theEvent,
  349.         AppleEvent                *theReply,
  350.         long                    refCon
  351.     )
  352. {
  353.         UNUSED(theEvent);
  354.         UNUSED(theReply);
  355.         UNUSED(refCon);
  356.         GLOBAL.currentEventIsAppleEvent = FALSE;
  357.         return (noErr);
  358. }
  359.  
  360. /*
  361.  * Unknown events go here. If the application provides an alert, call it.
  362.  * The initializer has provided a handler functions.
  363.  */
  364. static pascal OSErr
  365. AEUnknownHandler(
  366.         const AppleEvent        *theEvent,
  367.         AppleEvent                *theReply,
  368.         long                    refCon
  369.     )
  370. {
  371.         OSErr                    status;
  372.         OSType                    eventClass;
  373.         OSType                    eventID;
  374.         OSType                    typeCode;
  375.         Size                    actualSize;
  376.         Str255                    work;
  377.         
  378.         status = AEHandlerSetup(theEvent, theReply, refCon);
  379.         if (status == noErr) {
  380.             status = AEGetAttributePtr(
  381.                 theEvent,
  382.                 keyEventClassAttr,
  383.                 typeType,
  384.                 &typeCode,
  385.                 (Ptr) &eventClass,
  386.                 sizeof(eventClass),
  387.                 &actualSize
  388.             );
  389.         }
  390.         if (status == noErr) {
  391.             AEGetAttributePtr(
  392.                 theEvent,
  393.                 keyEventIDAttr,
  394.                 typeType,
  395.                 &typeCode,
  396.                 (Ptr) &eventID,
  397.                 sizeof(eventID),
  398.                 &actualSize
  399.             );
  400.         }
  401.         if (status == noErr) {
  402.             pstrcpy(work, "\pUnknown AppleEvent. Class ");
  403.             BlockMoveData(&eventClass, &work[work[0] + 1], sizeof (OSType));
  404.             work[0] += sizeof (OSType);
  405.             pstrcat(work, "\p, ID ");
  406.             BlockMoveData(&eventID, &work[work[0] + 1], sizeof (OSType));
  407.             work[0] += sizeof (OSType);
  408.             (*gAEUnknownHandlerMsgFunc)(work);
  409.         }
  410.         GLOBAL.currentEventIsAppleEvent = FALSE;
  411.         return (errAEHandlerNotFound);        
  412. }
  413.  
  414. /*
  415.  * This processes the Do Script event. The application provided a handler.
  416.  */
  417. static pascal OSErr
  418. AEDoScript(
  419.         const AppleEvent        *theEvent,
  420.         AppleEvent                *theReply,
  421.         long                    refCon
  422.     )
  423. {
  424.         CharsHandle                scriptHandle;
  425.         OSErr                    status;
  426.         
  427.         scriptHandle = NULL;
  428.         status = AEHandlerSetup(theEvent, theReply, refCon);
  429.         if (status == noErr)
  430.             status = AEGetChars(theEvent, keyDirectObject, &scriptHandle);
  431.         if (status == noErr)
  432.             status = AEGotRequiredParams(theEvent);
  433.         if (status == noErr) {
  434.             /*
  435.              * Make sure there's a null trailer.
  436.              */
  437.             status = PtrAndHand("", (Handle) scriptHandle, 1);
  438.         }
  439.         if (status == noErr) {
  440.             MoveHHi((Handle) scriptHandle);
  441.             HLock((Handle) scriptHandle);
  442.             status = (*gAEDoScriptHandlerFunc)(
  443.                         (Ptr) *scriptHandle,
  444.                         GetHandleSize((Handle) scriptHandle),
  445.                         theReply,
  446.                         refCon
  447.                 );
  448.         }
  449.         if (scriptHandle != NULL) {
  450.             DisposeHandle((Handle) scriptHandle);
  451.             scriptHandle = NULL;
  452.         }
  453.         GLOBAL.currentEventIsAppleEvent = FALSE;
  454.         return (status);
  455. }
  456.  
  457. /*
  458.  * Utilities
  459.  */
  460. /*
  461.  * Build an AppleEvent descriptor for a target address. The addressMode parameter
  462.  * chooses the target:
  463.  *    kSelfCurrentProcess    direct calls to this application (for scripting)
  464.  *    kSelfUsingPSN        event-loop based calls to this application (script debug)
  465.  *    kOtherApplication    dialog-based calls to an external application.
  466.  */
  467. pascal OSErr
  468. AEMakeTargetAddress(
  469.         AETargetAddressType        aeTargetAddressType,
  470.         AEDesc                    *theAddress,
  471.         StringPtr                targetName
  472.     )
  473. {
  474.         OSErr                    status;
  475.         ProcessSerialNumber        myPSN;
  476.         StringPtr                theTarget;
  477.         
  478.         theTarget = "\p";            /* Bogus initialize for MetroWerks            */
  479.         switch (aeTargetAddressType) {
  480.         case kAETargetSelfCurrentProcess:
  481.             /*
  482.              * Note that, if you use this case, the Apple Event
  483.              * Manager will bypass the event loop and call your
  484.              * handlers directly.
  485.              */
  486.             myPSN.highLongOfPSN = 0;
  487.             myPSN.lowLongOfPSN = kCurrentProcess;
  488.             theTarget = "\pLocal direct linkage"; 
  489.             goto makeDescriptor;
  490.         case kAETargetSelfUsingPSN:
  491.             /*
  492.              * This case always calls through the event loop.
  493.              */
  494.             status = GetCurrentProcess(&myPSN);
  495.             theTarget = "\pLocal linkage through event loop"; 
  496.             if (status == noErr) {
  497. makeDescriptor:    status = AECreateDesc(
  498.                         typeProcessSerialNumber,
  499.                         (Ptr) &myPSN,
  500.                         sizeof (ProcessSerialNumber),
  501.                         theAddress
  502.                     );
  503.             }
  504.             break;
  505.         case kAETargetOtherApplication:
  506.             status = AEBrowseForTarget(
  507.                         NULL, NULL, NULL, NULL, theAddress, theTarget);
  508.             break;
  509.         }
  510.         if (status == noErr && targetName != NULL)
  511.             BlockMoveData(theTarget, targetName, theTarget[0] + 1);
  512.         return (status);
  513. }
  514.  
  515. /*
  516.  * Call the PPC Toolbox browser to locate a target application.
  517.  *    dialogPrompt        -> "Choose a program to link to" if NULL
  518.  *    listHeader            -> "Programs"
  519.  *    theAddress            <- the result
  520.  *    targetName            <- the application name text for error alerts
  521.  */
  522. pascal OSErr
  523. AEBrowseForTarget(
  524.         ConstStr255Param        dialogPrompt,
  525.         ConstStr255Param        listHeader,
  526.         PPCFilterUPP            filterProcUPP,
  527.         ConstStr255Param        locNBPType,                
  528.         AEDesc                    *theAddress,
  529.         StringPtr                targetName
  530.     )
  531. {
  532.         LocationNameRec            theLoc;
  533.         PortInfoRec                theRec;
  534.         OSErr                    status;
  535.         TargetID                theID;
  536.  
  537.         status = PPCBrowser(
  538.                     dialogPrompt,
  539.                     listHeader,
  540.                     FALSE,            /* No default        */
  541.                     &theLoc,
  542.                     &theRec,
  543.                     filterProcUPP,    
  544.                     locNBPType
  545.                 );
  546.         if (status == noErr) {
  547.             /*
  548.              * Create a target descriptor
  549.              */
  550.             BlockMoveData(
  551.                 theRec.name.name,
  552.                 targetName,
  553.                 theRec.name.name[0] + 1
  554.             );
  555.             theID.name = theRec.name;
  556.             theID.location = theLoc;
  557.             status = AECreateDesc(
  558.                         typeTargetID,
  559.                         (Ptr) &theID,
  560.                         sizeof(theID),
  561.                         theAddress
  562.                     );
  563.         }
  564.         if (status == noErr)
  565.             ParamText(targetName, "\p", "\p", "\p");
  566.         return (status);
  567. }
  568.  
  569. /*
  570.  * Call IPCListPorts to locate a target application.
  571.  *    machineName            -> the machine to look for
  572.  *    targetNameVector    -> a vector (NULL terminated) of application name strings.
  573.  *    theAddress            <- the result
  574.  *    targetName            <- the application name text for error alerts
  575.  */
  576. pascal OSErr
  577. AELocateTarget(
  578.         ConstStr255Param        machineName,
  579.         const StringPtr            *targetNameVector,
  580.         AEDesc                    *theAddress,
  581.         StringPtr                actualTargetName
  582.     )
  583. {
  584.         LocationNameRec            locationNameRec;
  585.         OSErr                    status;
  586.         TargetID                theID;
  587.         IPCListPortsPBRec        ipcListPortsPBRec;
  588.         PPCPortRec                ppcPortRec;
  589.         PortInfoRec                portInfoRec;
  590.         short                    i;
  591.         short                    j;
  592. #define IPC        (ipcListPortsPBRec)
  593. #define LOC        (locationNameRec)
  594. #define PORT    (ppcPortRec)
  595. #define INFO    (portInfoRec)
  596.  
  597.         CLEAR(PORT);
  598.         PORT.nameScript = smRoman;
  599.         pstrcpy(PORT.name, "\p=");
  600.         PORT.portKindSelector = ppcByString;
  601.         pstrcpy(PORT.u.portTypeStr, "\p=");
  602.         CLEAR(LOC);
  603.         LOC.locationKindSelector = ppcNBPLocation;
  604.         pstrcpy(LOC.u.nbpEntity.objStr, (void *) machineName);
  605.         pstrcpy(LOC.u.nbpEntity.typeStr, "\pPPCToolBox");
  606.         AEGetMyZone(LOC.u.nbpEntity.zoneStr);
  607.         status = noErr;
  608.         for (i = 0; status == noErr; i++) {
  609.             CLEAR(IPC);
  610.             IPC.startIndex = i;
  611.             IPC.requestCount = 1;
  612.             IPC.portName = &PORT;
  613.             IPC.locationName = &LOC;
  614.             IPC.bufferPtr = &portInfoRec;
  615. //            status = IPCListPorts(&IPC, FALSE);
  616. //             not #defined in Marconi headers, use the  following
  617.             status = IPCListPortsSync(&IPC);
  618.             if (status == noErr) {
  619.                 BlockMoveData(
  620.                     INFO.name.name,
  621.                     actualTargetName,
  622.                     INFO.name.name[0] + 1
  623.                 );
  624.                 for (j = 0; targetNameVector[j] != NULL; j++) {
  625.                     if (EqualString(
  626.                             actualTargetName, targetNameVector[j], FALSE, FALSE)) {
  627.                         theID.name = INFO.name;
  628.                         theID.location = LOC;
  629.                         status = AECreateDesc(
  630.                                 typeTargetID,
  631.                                 (Ptr) &theID,
  632.                                 sizeof(theID),
  633.                                 theAddress
  634.                             );
  635.                         goto exit;
  636.                     }
  637.                 }
  638.             }
  639.         }
  640. exit:    return (status);
  641. #undef IPC
  642. #undef LOC
  643. #undef PORT
  644. #undef INFO
  645. }
  646.  
  647. /*
  648.  * This should be called before doing any user-interaction, such as alerts
  649.  * or dialogs. It returns FALSE if interaction is blocked at this time.
  650.  * The application should provide an idle function UPP. For example,
  651.  *
  652.  *        pascal Boolean
  653.  *        MyAEIdleProc(
  654.  *                const EventRecord        *theEventPtr,
  655.  *                long                    *sleepTime,
  656.  *                RgnHandle                *mouseRgn
  657.  *            )
  658.  *        {
  659.  *                if (theEventPtr->what == kHighLevelEvent)
  660.  *                    return (TRUE);
  661.  *                else {
  662.  *                    *sleepTime = ProcessThisEvent(theEventPtr);
  663.  *                    return (FALSE);
  664.  *                }
  665.  *        }        
  666.  */
  667. pascal Boolean
  668. AEInteractionOK(
  669.         AEIdleUPP                aeIdleUPP
  670.     )
  671. {
  672.         Boolean                    result;
  673.         OSErr                    status;
  674.  
  675.         if (GLOBAL.currentEventIsAppleEvent == FALSE)
  676.             result = TRUE;
  677.         else {
  678.             status = AEInteractWithUser(0, NULL, aeIdleUPP);
  679.             result = (status == noErr);
  680.         }
  681.         return (result);
  682. }
  683.  
  684. /*
  685.  * AEGotRequiredParams fails if not all required parameters have been extracted.
  686.  * Call this after retrieving all required parameters before actually processing
  687.  * the event. This sets gCurrentAEStatus to noErr if it succeeds.
  688.  *
  689.  * If required parameters remain, return errAEParamMissed.
  690.  */
  691. pascal OSErr
  692. AEGotRequiredParams(
  693.         const AppleEvent        *theEvent
  694.     )
  695. {
  696.         DescType                descType;
  697.         Size                    actualSize;
  698.         OSErr                    status;
  699.         
  700.         status = AEGetAttributePtr(
  701.                 theEvent,
  702.                 keyMissedKeywordAttr,
  703.                 typeWildCard,
  704.                 &descType,
  705.                 NULL,
  706.                 0,
  707.                 &actualSize
  708.             );
  709.         if (status == errAEDescNotFound) {
  710.             GLOBAL.currentAEStatus = noErr;
  711.             status = noErr;
  712.         }
  713.         else {
  714.             status = errAEParamMissed;
  715.         }
  716.         return (status);
  717. }
  718.  
  719. /*
  720.  * All apple events call this function initially to store common information.
  721.  */
  722. pascal OSErr
  723. AEHandlerSetup(
  724.         const AppleEvent        *theEvent,
  725.         AppleEvent                *theReply,
  726.         long                    refCon
  727.     )
  728. {
  729.         OSErr                    status;
  730.         DescType                actualType;
  731.         Size                    actualSize;
  732.  
  733.         /*
  734.          * Here's where we add the Frontier "shared script" cancel handler.
  735.          */
  736.         GLOBAL.currentAEEvent = theEvent;
  737.         GLOBAL.currentAEReply = theReply;
  738.         GLOBAL.currentAERefCon = refCon;
  739.         GLOBAL.currentAEStatus = errAEEventNotHandled;
  740.         GLOBAL.currentEventIsAppleEvent = TRUE;
  741.         /*
  742.          * Try to extract the class and type parameters, then switch on the
  743.          * event and process what we can. Note that GLOBAL.currentAEStatus is
  744.          * initializad to an error code: the final caller must set the status to
  745.          * noErr if the event was correctly handled. Normally, this is done
  746.          * by AEGotRequiredParams
  747.          */
  748.         status = AEGetAttributePtr(
  749.                     theEvent,
  750.                     keyEventClassAttr,
  751.                     typeType,
  752.                     &actualType,
  753.                     (Ptr) &GLOBAL.currentAEEventClass,
  754.                     sizeof GLOBAL.currentAEEventClass,
  755.                     &actualSize
  756.                 );
  757.         if (status == noErr) {
  758.             status = AEGetAttributePtr(
  759.                         theEvent,
  760.                         keyEventIDAttr,
  761.                         typeType,
  762.                         &actualType,
  763.                         (Ptr) &GLOBAL.currentAEEventID,
  764.                         sizeof GLOBAL.currentAEEventID,
  765.                         &actualSize
  766.                     );
  767.         }
  768.         if (status == noErr) {
  769.             status = AEGetAttributePtr(
  770.                     theEvent,
  771.                     keyInteractLevelAttr,
  772.                     typeInteger,
  773.                     &actualType,
  774.                     (Ptr) &GLOBAL.currentAEIntractionLevel,
  775.                     sizeof GLOBAL.currentAEIntractionLevel,
  776.                     &actualSize
  777.             );
  778.         }
  779.         return (status);
  780. }
  781.  
  782. /*
  783.  * These functions get and set data in the AppleEvent. They are only needed
  784.  * if we intend to receive events.
  785.  */
  786.  
  787. /*
  788.  * AEGetShort extracts a signed short integer from the parameter list.
  789.  * Return noErr on success, errAEDescNotFound if the parameter was missing.
  790.  */
  791. pascal OSErr
  792. AEGetShort(
  793.         const AppleEvent        *theEvent,
  794.         DescType                parameterKey,
  795.         short                    *result
  796.     )
  797. {
  798.         OSErr                    status;
  799.         Size                    actualSize;
  800.         DescType                actualType;
  801.  
  802.         status = AEGetParamPtr(
  803.                     theEvent,
  804.                     parameterKey,
  805.                     typeSMInt,
  806.                     &actualType,
  807.                     (Ptr) result,
  808.                     sizeof (short),
  809.                     &actualSize
  810.                 );
  811.         return (status);
  812. }
  813.  
  814. /*
  815.  * AEGetLong extracts an signed short integer from the parameter list.
  816.  */
  817. pascal OSErr
  818. AEGetLong(
  819.         const AppleEvent        *theEvent,
  820.         DescType                parameterKey,
  821.         long                    *result
  822.     )
  823. {
  824.         OSErr                    status;
  825.         Size                    actualSize;
  826.         DescType                actualType;
  827.  
  828.         status = AEGetParamPtr(
  829.                     theEvent,
  830.                     parameterKey,
  831.                     typeInteger,
  832.                     &actualType,
  833.                     (Ptr) result,
  834.                     sizeof (long),
  835.                     &actualSize
  836.                 );
  837.         return (status);
  838. }
  839.  
  840. /*
  841.  * AEGetBoolean extracts a Boolean from the parameter list.
  842.  */
  843. pascal OSErr
  844. AEGetBoolean(
  845.         const AppleEvent        *theEvent,
  846.         DescType                parameterKey,
  847.         Boolean                    *result
  848.     )
  849. {
  850.         OSErr                    status;
  851.         Size                    actualSize;
  852.         DescType                actualType;
  853.         
  854.         status = AEGetParamPtr(
  855.                     theEvent,
  856.                     parameterKey,
  857.                     typeBoolean,
  858.                     &actualType,
  859.                     (Ptr) result,
  860.                     sizeof (Boolean),
  861.                     &actualSize
  862.                 );
  863.         return (status);
  864. }
  865.  
  866. /*
  867.  * GetAEChars extracts a text item from the parameter list, returning it in a
  868.  * newly-allocated CharsHandle. The caller must dispose the handle.
  869.  */
  870. pascal OSErr
  871. AEGetChars(
  872.         const AppleEvent        *theEvent,
  873.         DescType                parameterKey,
  874.         CharsHandle                *result
  875.     )
  876. {
  877.         OSErr                    status;
  878.         AEDesc                    theDesc;
  879.  
  880.         status = AEGetParamDesc(
  881.                         theEvent,
  882.                         parameterKey,
  883.                         typeChar,
  884.                         &theDesc
  885.                     );
  886.         if (status == noErr)
  887.             *result = (CharsHandle) theDesc.dataHandle;
  888.         return (status);
  889. }
  890.  
  891. /*
  892.  * GetAEString extracts a Str255 from the parameter list.
  893.  */
  894. pascal OSErr
  895. AEGetString(
  896.         const AppleEvent        *theEvent,
  897.         DescType                parameterKey,
  898.         StringPtr                result
  899.     )
  900. {
  901.         OSErr                    status;
  902.         Size                    actualSize;
  903.         DescType                actualType;
  904.  
  905.         status = AEGetParamPtr(
  906.                     theEvent,
  907.                     parameterKey,
  908.                     typeChar,
  909.                     &actualType,
  910.                     (Ptr) &result[1],
  911.                     sizeof (Str255) - 1,
  912.                     &actualSize
  913.                 );
  914.         result[0] = actualSize;
  915.         return (status);
  916. }
  917.  
  918. /*
  919.  * AEPutShort stores a short integer into an AppleEvent reply.
  920.  */
  921. pascal OSErr
  922. AEPutShort(
  923.         AppleEvent                *theReply,
  924.         DescType                parameterKey,
  925.         short                    value
  926.     )
  927. {
  928.         OSErr                    status;
  929.         
  930.         status = AEPutParamPtr(
  931.                     theReply,
  932.                     parameterKey,
  933.                     typeSMInt,
  934.                     (Ptr) &value,
  935.                     sizeof value
  936.                 );
  937.         return (status);
  938. }
  939.  
  940. /*
  941.  * AEPutBoolean stores a Boolean into the AppleEvent reply.
  942.  */
  943. pascal OSErr
  944. AEPutBoolean(
  945.         AppleEvent                *theReply,
  946.         DescType                parameterKey,
  947.         Boolean                    value
  948.     )
  949. {
  950.         OSErr                    status;
  951.         
  952.         status = AEPutParamPtr(
  953.                     theReply,
  954.                     parameterKey,
  955.                     typeBoolean,
  956.                     (Ptr) &value,
  957.                     sizeof value
  958.                 );
  959.         return (status);
  960. }
  961.  
  962. /*
  963.  * AEPutLong stores a long integer into the AppleEvent reply.
  964.  */
  965. pascal OSErr
  966. AEPutLong(
  967.         AppleEvent                *theReply,
  968.         DescType                parameterKey,
  969.         long                    value
  970.     )
  971. {
  972.         OSErr                    status;
  973.         
  974.         status = AEPutParamPtr(
  975.                     theReply,
  976.                     parameterKey,
  977.                     typeInteger,
  978.                     (Ptr) &value,
  979.                     sizeof value
  980.                 );
  981.         return (status);
  982. }
  983.  
  984. /*
  985.  * AEPutStringHandle stores a StringHandle into the AppleEvent reply.
  986.  */
  987. pascal OSErr
  988. AEPutStringHandle(
  989.         AppleEvent                *theReply,
  990.         DescType                parameterKey,
  991.         const StringHandle        value
  992.     )
  993. {
  994.         OSErr                    status;
  995.         short                    lockState;
  996.         
  997.         lockState = HGetState((Handle) value);
  998.         HLock((Handle) value);
  999.         status = AEPutString(theReply, parameterKey, *value);
  1000.         HSetState((Handle) value, lockState);
  1001.         return (status);
  1002. }
  1003.  
  1004. /*
  1005.  * AEPutCharsHandle stores a CharsHandle into the AppleEvent reply.
  1006.  */
  1007. pascal OSErr
  1008. AEPutCharsHandle(
  1009.         AppleEvent                *theReply,
  1010.         DescType                parameterKey,
  1011.         const CharsHandle        value
  1012.     )
  1013. {
  1014.         OSErr                    status;
  1015.         short                    lockState;
  1016.         
  1017.         lockState = HGetState((Handle) value);
  1018.         HLock((Handle) value);
  1019.         status = AEPutParamPtr(
  1020.                     theReply,
  1021.                     parameterKey,
  1022.                     typeChar,
  1023.                     (Ptr) *value,
  1024.                     GetHandleSize((Handle) value)
  1025.                 );
  1026.         HSetState((Handle) value, lockState);
  1027.         return (status);
  1028. }
  1029.  
  1030.  
  1031. /*
  1032.  * AEPutString stores a Str255 into the AppleEvent reply.
  1033.  */
  1034. pascal OSErr
  1035. AEPutString(
  1036.         AppleEvent                *theReply,
  1037.         DescType                parameterKey,
  1038.         ConstStr255Param        value
  1039.     )
  1040. {
  1041.         OSErr                    status;
  1042.         
  1043.         status = AEPutParamPtr(
  1044.                     theReply,
  1045.                     parameterKey,
  1046.                     typeChar,
  1047.                     (Ptr) &value[1],
  1048.                     value[0]
  1049.                 );
  1050.         return (status);
  1051. }
  1052.  
  1053. /*
  1054.  * Local function for AELocateTarget
  1055.  */
  1056. static void
  1057. AEGetMyZone(
  1058.         Str32                    zoneName
  1059.     )
  1060. {
  1061.         XPPParamBlock            pb;
  1062.         OSErr                    status;
  1063. #define PB    (pb)
  1064. #define kXPPTimeout                3
  1065. #define kXPPRetry                4
  1066.  
  1067.         CLEAR(PB);
  1068.         PB.XCALL.xppTimeout = kXPPTimeout;
  1069.         PB.XCALL.xppRetry = kXPPRetry;
  1070.         PB.XCALL.zipBuffPtr = (Ptr) zoneName;
  1071.         PB.XCALL.zipInfoField[0] = 0;
  1072.         PB.XCALL.zipInfoField[1] = 0;
  1073.         status = GetMyZone(&PB, FALSE);
  1074.         if (status == noBridgeErr) {
  1075.             zoneName[0] = 1;
  1076.             zoneName[1] = '*';
  1077.         }
  1078.         else if (status != noErr) {
  1079.             zoneName[0] = 0;
  1080.         }
  1081. #undef PB
  1082. }
  1083.  
  1084. static void
  1085. ClearMemory(
  1086.         void                    *dataPtr,
  1087.         register long            size
  1088.     )
  1089. {
  1090.         register char            *ptr;
  1091.  
  1092.         ptr = (char *) dataPtr;
  1093.         while (size > 0) {
  1094.             *ptr++ = 0;
  1095.             --size;
  1096.         }
  1097. }
  1098.  
  1099. static void
  1100. pstrcpy(
  1101.         StringPtr                dst,
  1102.         ConstStr255Param        src
  1103.     )
  1104. {
  1105.         BlockMoveData(src, dst, src[0] + 1);
  1106. }
  1107.  
  1108. static void
  1109. pstrcat(
  1110.         StringPtr                dst,
  1111.         ConstStr255Param        src
  1112.     )
  1113. {
  1114.         short                    length;
  1115.         
  1116.         length = 255 - dst[0];
  1117.         if (length > src[0])
  1118.             length = src[0];
  1119.         BlockMoveData(&src[1], &dst[1] + dst[0], length);
  1120.         dst[0] += length;
  1121. }
  1122.  
  1123.